package org.ht.controller;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import javax.sql.DataSource;
import javax.swing.JOptionPane;

import org.azj.dbOperatorComponent.ICommand;
import org.azj.dbOperatorComponent.IDbNonQueryOperation;
import org.azj.dbOperatorComponent.IDbQueryOperation;
import org.azj.dbOperatorComponent.IJobManager;
import org.azj.dbOperatorComponent.OperableTable;
import org.azj.dbOperatorComponent.SelectFilter;
import org.azj.dbOperatorComponent.TransactionHelper;
import org.azj.logHelper.LOG;
import org.azj.logHelper.LOG_COMPONENT;
import org.azj.logHelper.LOG_LEVEL;
import org.ht.combotable.ComboTableFactory;
import org.ht.config.ColumnInfoXmlReader;
import org.ht.config.ConstField;
import org.ht.config.ImageType;
import org.ht.database.DataBase;
import org.ht.entity.Case;
import org.ht.entity.ImageTag;
import org.ht.exception.CannotOmitException;
import org.ht.global.DbTableNames;
import org.ht.global.Global;
import org.ht.util.StringUtil;
import org.ht.viewer.CaseDialog;

public class ControlCaseDialog {
	private CaseDialog caseDialog;

	public ControlCaseDialog(CaseDialog caseDialog) {
		this.caseDialog = caseDialog;
	}

	/**
	 * 保存的主逻辑
	 * 
	 * @param thecase
	 *            病例
	 * @return 是否保存成功
	 * @throws Exception
	 */
	public boolean save(Case thecase) throws Exception {
		ICommand command;
		IJobManager jobManager = new TransactionHelper(DataBase.getDataBase());

		// 保存基本信息
		command = generateInsertCommands(thecase.getBasicInfo().property,
				DbTableNames.FullTblBasicInfo);
		jobManager.addJob(command);

		// 保存术前信息
		command = generateInsertCommands(thecase.getOperationBefore().property,
				DbTableNames.FullTblBeforeOp);
		jobManager.addJob(command);

		// 保存术中信息
		command = generateInsertCommands(thecase.getOperationMiddle().property,
				DbTableNames.FullTblMidOp);
		jobManager.addJob(command);

		// 保存术后信息
		command = generateInsertCommands(thecase.getOperationAfter().property,
				DbTableNames.FullTblPostOp);
		jobManager.addJob(command);

		// 保存图片表
		ArrayList<ICommand> commands = generateInsertCommandsForImageTable(DbTableNames.fullTblImage);
		for (ICommand iCommand : commands) {
			jobManager.addJob(iCommand);
		}

		// 事务处理失败就返回
		if (null == MainController.doJobsInTransaction(jobManager)) {
			return false;
		}

		// TODO
		// 保存具体插入的数值，以显示在界面中
		List<List<HashMap<String, Object>>> result = getPaientInfo(thecase
				.getBasicInfo().property.get(ImageType.PID));

		// 事务处理失败就返回
		if (null == result) {
			return false;
		}

		HashMap<String, Object> info = result.get(0).get(0);

		Case newcase = Global.table.helper.getController().queryCase(
				thecase.getPid());
		// for (String key :set){
		// Object obj = info.get(key);
		//
		// String value = "";
		// DbTableFactory.getDbTable(DbTableNames.FullTblBasicInfo).getColumn(key).getDataTypeName();
		//
		//
		// newcase.getBasicInfo().property.put(key, value);
		// }
		// 显示在表中
		Global.table.helper.show(newcase,
				ComboTableFactory.instance.getVcolumn());
		return true;
	}

	/**
	 * 修改的主逻辑
	 * 
	 * @param thecase
	 *            病例
	 * @return 是否修改成功
	 * @throws Exception
	 */
	public boolean update(Case thecase) throws Exception {
		ICommand command;
		IJobManager jobManager = new TransactionHelper(DataBase.getDataBase());

		String pid = thecase.getPid();
		// 基本信息
		command = generateUpdateCommands(pid, thecase.getBasicInfo().property,
				DbTableNames.FullTblBasicInfo);
		jobManager.addJob(command);

		// 术前信息
		command = generateUpdateCommands(pid,
				thecase.getOperationBefore().property,
				DbTableNames.FullTblBeforeOp);
		jobManager.addJob(command);

		// 术中信息
		command = generateUpdateCommands(pid,
				thecase.getOperationMiddle().property,
				DbTableNames.FullTblMidOp);
		jobManager.addJob(command);

		// 术后信息
		command = generateUpdateCommands(pid,
				thecase.getOperationAfter().property,
				DbTableNames.FullTblPostOp);
		jobManager.addJob(command);

		// 保存图片表

		// 先处理数字和路径
		caseDialog.img_mri.setText(StringUtil.filterNum(caseDialog.img_mri
				.getText()));
		caseDialog.img_b.setText(StringUtil.filterNum(caseDialog.img_b
				.getText()));
		caseDialog.img_ct.setText(StringUtil.filterNum(caseDialog.img_ct
				.getText()));
		caseDialog.img_x.setText(StringUtil.filterNum(caseDialog.img_x
				.getText()));

		caseDialog.img_mrilist = StringUtil.filterUrl(caseDialog.img_mrilist);
		caseDialog.img_blist = StringUtil.filterUrl(caseDialog.img_blist);
		caseDialog.img_ctlist = StringUtil.filterUrl(caseDialog.img_ctlist);
		caseDialog.img_xlist = StringUtil.filterUrl(caseDialog.img_xlist);

		ArrayList<ICommand> commands = generateDeleteCommandsForImageTable(DbTableNames.fullTblImage);
		for (ICommand iCommand : commands) {
			jobManager.addJob(iCommand);
		}

		commands = generateInsertCommandsForImageTable(DbTableNames.fullTblImage);
		for (ICommand iCommand : commands) {
			jobManager.addJob(iCommand);
		}

		// 事务处理失败就返回
		if (null == MainController.doJobsInTransaction(jobManager)) {
			return false;
		}

		// TODO
		// 保存具体插入的数值，以显示在界面中
		List<List<HashMap<String, Object>>> result = getPaientInfo(thecase
				.getBasicInfo().property.get(ImageType.PID));

		// 事务处理失败就返回
		if (null == result) {
			return false;
		}

		HashMap<String, Object> info = result.get(0).get(0);

		Case newcase = Global.table.helper.getController().queryCase(
				thecase.getPid());
		// for (String key :set){
		// Object obj = info.get(key);
		//
		// String value = "";
		// DbTableFactory.getDbTable(DbTableNames.FullTblBasicInfo).getColumn(key).getDataTypeName();
		//
		//
		// newcase.getBasicInfo().property.put(key, value);
		// }
		// 显示在表中
		Global.table.helper.show(newcase,
				ComboTableFactory.instance.getVcolumn());
		return true;
	}

	// TODO 根据PID查东西,待完善
	private List<List<HashMap<String, Object>>> getPaientInfo(String pid)
			throws Exception, SQLException {
		ICommand command;
		IJobManager jobManager = new TransactionHelper(DataBase.getDataBase());

		command = generateQueryCommands("*",
				ImageType.PID + " = '" + pid + "'",
				DbTableNames.FullTblBasicInfo);
		jobManager.addJob(command);
		// 事务处理失败就返回
		List<List<HashMap<String, Object>>> result = MainController
				.doJobsInTransaction(jobManager);
		return result;
	}

	private ICommand generateInsertCommands(HashMap<String, String> contents,
			String tableFullName) throws Exception {

		String tableName = tableFullName.substring(tableFullName
				.lastIndexOf('.') + 1);
		IDbNonQueryOperation tableUnit = new OperableTable(
				DataBase.getDataBase(), DbTableNames.SchemaName, tableName);
		// 有未填值或者别的什么原因会抛异常出去
		setCaseFromUI(contents, tableFullName);
		HashMap<String, String> newcontents = changeFullName(contents,
				tableFullName);
		return tableUnit.getInsertPartialCommand(newcontents);
	}

	// 删除图像
	private ArrayList<ICommand> generateDeleteCommandsForImageTable(
			String tableFullName) throws Exception {
		ArrayList<ICommand> iCommands = new ArrayList<ICommand>();
		addIfNotNull(deleteImages(caseDialog.img_mrilist,DataBase.getDataBase()), iCommands);
		addIfNotNull(deleteImages(caseDialog.img_blist,DataBase.getDataBase()), iCommands);
		addIfNotNull(deleteImages(caseDialog.img_ctlist,DataBase.getDataBase()), iCommands);
		addIfNotNull(deleteImages(caseDialog.img_xlist,DataBase.getDataBase()), iCommands);
		
		return iCommands;
	}

	private void addIfNotNull(ICommand command, ArrayList<ICommand> iCommands) {
		if (command != null) {
			iCommands.add(command);
		}
	}

	// 调整表名和日志
	private ICommand deleteImages(List<String> toDeleteImages, DataSource ds) {

		if (toDeleteImages.size() == 0) {
			return null;
		}
		
		IDbNonQueryOperation tableUnit = null;
		ICommand command = null;
		try {
			tableUnit = new OperableTable(ds, DbTableNames.SchemaName,
					DbTableNames.TblImage);
		} catch (SQLException e) {
			LOG.WriteLog(LOG_LEVEL.CRITICAL, LOG_COMPONENT.LOG_COMP_DB_CHANGE, "数据库连接失败 ：" + e.getMessage());
			return null;
		}

		String whereFilter = "";
		int id = 0;

		for (String toDeleteImage : toDeleteImages) {
			try {
				id = Integer.parseInt(toDeleteImage);
			} catch (NumberFormatException nfe) {
				continue;
			}
			whereFilter += String.format("imageId = %d OR ", id);
		}
		// remove the last OR
		whereFilter = whereFilter.substring(0, whereFilter.lastIndexOf("OR") - 1);
		command = tableUnit.getDeleteCommand(whereFilter);

		return command;
	}

	private ArrayList<ICommand> generateInsertCommandsForImageTable(
			String tableFullName) throws Exception {
		String tableName = tableFullName.substring(tableFullName
				.lastIndexOf('.') + 1);
		IDbNonQueryOperation tableUnit = new OperableTable(
				DataBase.getDataBase(), DbTableNames.SchemaName, tableName);
		// setCaseFromUI(contents, tableFullName);
		// 图像表特殊处理
		ArrayList<ICommand> iCommands = new ArrayList<ICommand>();

		ArrayList<ImageTag> imageTags = caseDialog.getImageURL();
		for (ImageTag imageTag : imageTags) {
			HashMap<String, String> contents = new HashMap<String, String>();

			contents.put(ImageType.PID, caseDialog.PatientId.getText());
			contents.put(ImageType.TYPE, String.valueOf(imageTag.type));
			contents.put(ImageType.IMG, imageTag.url);
			HashMap<String, String> newcontents = changeFullName(contents,
					tableFullName);
			iCommands.add(tableUnit.getInsertPartialCommand(newcontents));
		}
		return iCommands;
	}

	private ICommand generateUpdateCommands(String pid,
			HashMap<String, String> contents, String tableFullName)
			throws Exception {

		String tableName = tableFullName.substring(tableFullName
				.lastIndexOf('.') + 1);
		IDbNonQueryOperation tableUnit = new OperableTable(
				DataBase.getDataBase(), DbTableNames.SchemaName, tableName);
		// 有未填值或者别的什么原因会抛异常出去
		setCaseFromUI(contents, tableFullName);
		HashMap<String, String> newcontents = changeFullName(contents,
				tableFullName);
		String where = ConstField.PID + " = '" + pid + "'";
		return tableUnit.getUpdatePartialCommand(where, newcontents);
	}

	private ICommand generateQueryCommands(String columns, String where,
			String tableFullName) throws Exception {
		String tableName = tableFullName.substring(tableFullName
				.lastIndexOf('.') + 1);
		IDbQueryOperation tableUnit = new OperableTable(DataBase.getDataBase(),
				DbTableNames.SchemaName, tableName);
		SelectFilter selectFilter = new SelectFilter(columns, where, null,
				null, null);
		return tableUnit.getSelectCommand(selectFilter);
	}

	private HashMap<String, String> changeFullName(
			HashMap<String, String> contents, String tblName) {
		Set<String> keyset = contents.keySet();
		HashMap<String, String> newcontents = new HashMap<String, String>();
		for (String key : keyset) {
			newcontents.put(tblName + "." + key, contents.get(key));
		}
		return newcontents;
	}

	/**
	 * 从界面取数据
	 * 
	 * @param contents
	 * @throws Exception
	 */
	private void setCaseFromUI(HashMap<String, String> contents, String tblName)
			throws Exception {
		Set<String> keyset = contents.keySet();
		List<String> unfilledList = new ArrayList<String>();
		HashMap<String, String> tmp = ColumnInfoXmlReader.getXmlReader()
				.getCannotOmitItems();
		for (String key : keyset) {
			String val = caseDialog.getText(key);

			// TODO 需要这里的判断

			if (val == null || val.isEmpty()) {
				if (tmp.containsKey(key)) {
					unfilledList.add(key);
				}
				val = "";
			}

			contents.put(key, val);
		}

		 //TODO 此处如果注释掉会跳过空值检查
		 if (unfilledList.isEmpty() == false) {
		 unfilledList(tblName, unfilledList);
		 }
	}

	/**
	 * 界面未填完整,处理并抛异常
	 * 
	 * @param tblName
	 * @param unfilledList
	 * @throws CannotOmitException
	 */
	private void unfilledList(String tblName, List<String> unfilledList)
			throws CannotOmitException {
		if (unfilledList.isEmpty() == false) {
			StringBuffer sb = new StringBuffer();
			for (String s : unfilledList) {
				sb.append(s + ",");
			}
			String message = "界面页[" + tblName + "]必须填充所有的内容才能够提交!" + sb;
			JOptionPane.showMessageDialog(null, message, "错误",
					JOptionPane.ERROR_MESSAGE);
			throw new CannotOmitException(message);
		}
	}

	public List<String> queryImagesByPid(String pid) {
		List<String> urls = new ArrayList<String>();

		IDbQueryOperation tableUnit;
		try {
			tableUnit = new OperableTable(DataBase.getDataBase(),
					DbTableNames.SchemaName, DbTableNames.TblImage);

			SelectFilter selectFilter = new SelectFilter();
			for (int i = 0; i < 4; i++) {
				selectFilter.setColumnList("imageId");
				selectFilter.setWhereFilter("PatientId='" + pid
						+ "' and ImageType='" + (i + 1) + "'");
				List<HashMap<String, Object>> rs = tableUnit.getSelectCommand(
						selectFilter).doCommand(DataBase.getDataBase());
				String url = "";
				for (HashMap<String, Object> tmpHash : rs) {
					url += tmpHash.get("LHGANGCHANG.TBL_IMAGE.IMAGEID") + ";";
				}
				urls.add(url);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return urls;
	}

}
